﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Collections;
using DVBViewerServer;
using System.Drawing;
using System.Diagnostics;

namespace DVBViMon
{
    public delegate void DVBViewerClosedEventHandler(object obj, EventArgs e);

    public class DvbvComMngr
    {
        private DVBViewer dvbv;
        private Dictionary<string, object> ht;

        /// <summary>
        /// Gets a value indicating whether this instance is connected.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is connected; otherwise, <c>false</c>.
        /// </value>
        public bool IsConnected
        {
            get
            {
                if (dvbv != null)
                {
                    double vol;
                    try
                    {
                        vol = this.dvbv.Volume;
                    }
                    catch (COMException)
                    {
                        return (false);
                    }
                    catch (Exception)
                    {
                        return (false);
                    }
                    return (true);
                }
                else
                    return (false);
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DvbvComMngr"/> class.
        /// </summary>
        public DvbvComMngr()
        {
        }

        /// <summary>
        /// Initialize the COM Interface to DVBViewer Software
        /// </summary>
        /// <returns>true if successfully initialized, false otherwiese</returns>
        public bool connectToDVBViewerComInterface()
        {
            try
            {
                this.dvbv = (DVBViewer)System.Runtime.InteropServices.Marshal.GetActiveObject("DVBViewerServer.DVBViewer");
                //Register EventHandler for ChannelChange action
//                this.dvbv.Events.OnChannelChange += dvbv_ChannelChange;
//                this.dvbv.Events.onDVBVClose += Events_onDVBVClose;                              
            }
            catch (Exception)
            {                
                return false;
            }

            return true;
        }

        void Events_onDVBVClose()
        {
            OnDVBViewerClosed(EventArgs.Empty);
            this.dvbv.Events.onDVBVClose -= Events_onDVBVClose;
        }


        private void dvbv_ChannelChange(int ChannelNr)
        {
            /* do nothing --> Event Seems not to be fired every time a channel is changed */
//            Debug.Print("Channel changed : " + ChannelNr.ToString() + " " + this.dvbv.CurrentChannel.Name);
        }


        /// <summary>
        /// Gathers display-relevant information from DVBViewer COM interface
        /// </summary>
        /// <returns>returns the Hashtable with the values, null if error</returns>
        public Dictionary<string, object> getInformationFromDVBViewer()
        {
            this.ht = new Dictionary<string, object>();
            ht.Add("activeChannel", "");
            ht.Add("title", "");
            ht.Add("isRecording", false);
            ht.Add("progress", "");
            ht.Add("audioMode", 0);
            ht.Add("volume", 0.0);
            ht.Add("isMediaPlayback", false);
            ht.Add("isTimeShift", false);
            ht.Add("isDVD", false);
            ht.Add("percentage", "");
            ht.Add("mediaTitle", "");
            ht.Add("propertyValues", "");
            ht.Add("selectedItem", "");
            ht.Add("isOSD", false);
            ht.Add("currentplaytime", "00:00:00");
            ht.Add("duration", "00:00:00");
            ht.Add("remain", "00:00:00");

            try
            {
                string channelName = this.dvbv.OSD.ChannelName;
                if (channelName == null)
                    ht["activeChannel"] = string.Empty;
                else
                    ht["activeChannel"] = channelName;
            }
            catch
            {
            }

            try
            {
                string title = this.dvbv.EPGManager.EPGNow.Title;
                if (title == null)
                    title = string.Empty;
                else
                    ht["title"] = title;
            }
            catch
            {
            }

            try
            {
                bool recording = this.dvbv.TimerManager.Recording;
                ht["isRecording"] = recording;
            }
            catch
            {
            }

            try
            {
                string progress = dvbv.DataManager.get_Value("#TV.Now.percentage");
                if (progress == null)
                    ht["progress"] = "0";
                else
                {
                    if (progress == "-1")
                        ht["progress"] = "0";
                    else
                        ht["progress"] = progress;
                }
            }
            catch
            {
            }

            try
            {
                int audioMode = this.dvbv.Audiomode();
                ht["audioMode"] = audioMode;
            }
            catch
            {
            }

            try
            {
                double volume = this.dvbv.Volume;
                ht["volume"] = volume;
            }
            catch
            {
            }

            try
            {
                bool mediaPlayback = this.dvbv.isMediaplayback();
                ht["isMediaPlayback"] = mediaPlayback;
            }
            catch
            {

            }

            try
            {
                bool dvd = this.dvbv.isDVD();
                ht["isDVD"] = dvd;
            }
            catch
            {

            }

            try
            {
                bool timeShift = this.dvbv.IsTimeshift();
                ht["isTimeshift"] = timeShift;
            }
            catch
            {

            }

            try
            {
                string percentage = this.dvbv.DataManager.get_Value("#percentage");
                if (percentage == null)
                    ht["percentage"] = "0";
                else
                    ht["percentage"] = percentage;
            }
            catch
            {
            }

            try
            {
                string mTitle = this.dvbv.DataManager.get_Value("#Media.title");
                if (mTitle == null)
                    ht["mediaTitle"] = "";
                else
                    ht["mediaTitle"] = mTitle;
            }
            catch
            {
            }

            //try
            //{
            //    ht["propertyValues"] = this.dvbv.DataManager.GetAll();
            //}
            //catch
            //{
            //}

            try
            {
                string selectedItem = this.dvbv.DataManager.get_Value("#selecteditem");
                if (selectedItem == null)
                    ht["selectedItem"] = "";
                else
                    ht["selectedItem"] = selectedItem;
            }
            catch
            {
            }

            try
            {
                ht["isOSD"] = this.dvbv.OSD.isVisible();
            }
            catch
            {
            }

            try
            {
                string cPlayTime = this.dvbv.DataManager.get_Value("#currentplaytime");
                if (cPlayTime == null)
                    ht["currentplaytime"] = "00:00:00";
                else
                    ht["currentplaytime"] = cPlayTime;
            }
            catch
            {
            }

            try
            {
                string cDur = this.dvbv.DataManager.get_Value("#duration");
                if (cDur == null)
                    ht["duration"] = "00:00:00";
                else
                    ht["duration"] = cDur;
            }
            catch
            {
            }

            try
            {
                string cRem = this.dvbv.DataManager.get_Value("#remain");
                if (cRem == null)
                    ht["remain"] = "00:00:00";
                else
                    ht["remain"] = cRem;
            }
            catch
            {
            }

            return ht;
        }



        public event DVBViewerClosedEventHandler DVBViewerClosed;

        protected virtual void OnDVBViewerClosed( EventArgs e)
        {
            DVBViewerClosedEventHandler handler = DVBViewerClosed;
            if (handler != null)
                handler(this, e);
        }

        internal void UnsubscribeEvents()
        {
//            try
//            {
////                this.dvbv.Events.OnChannelChange -= dvbv_ChannelChange;
//                this.dvbv.Events.onDVBVClose -= Events_onDVBVClose;
//            }
//            catch
//            {
//            }
        }
    }
}
